package rename_tab

import (
	"file_explorer/common/log"
	"file_explorer/common/util"
	"file_explorer/model"
	"file_explorer/service/eventbus"
	"file_explorer/view/packed_widgets"
	"file_explorer/view/store"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"github.com/samber/lo"
)

type RenameFileList struct {
	*fyne.Container

	toolbar   *widget.Toolbar
	fileTable *packed_widgets.Table

	tabCtx *store.RenameTabContext
}

// 从context回写CheckList状态
func (fileList *RenameFileList) reloadCheckList() {
	checkItemSet := make(map[*model.ModifiedFileInfo]struct{})
	for _, checkItem := range fileList.tabCtx.CheckedFiles {
		checkItemSet[checkItem] = struct{}{}
	}
	checkIndexList := make([]int, 0, len(checkItemSet))
	for i, fileInfo := range fileList.tabCtx.FileInfos {
		if _, ok := checkItemSet[fileInfo]; ok {
			checkIndexList = append(checkIndexList, i)
		}
	}
	fileList.fileTable.Checklist.SetCheckIndexList(checkIndexList)
}

func (fileList *RenameFileList) buildToolbar() {
	deleteButton := packed_widgets.NewButton("移除", theme.ContentRemoveIcon(), func() {
		checkedFileList := make(map[*model.ModifiedFileInfo]struct{})
		for _, checkedFile := range fileList.tabCtx.CheckedFiles {
			checkedFileList[checkedFile] = struct{}{}
		}

		newFiles := make([]*model.ModifiedFileInfo, 0, len(fileList.tabCtx.FileInfos))
		for _, fileInfo := range fileList.tabCtx.FileInfos {
			if _, ok := checkedFileList[fileInfo]; !ok {
				newFiles = append(newFiles, fileInfo)
			}
		}
		fileList.tabCtx.CheckedFiles = nil
		fileList.tabCtx.FileInfos = newFiles
		fileList.fileTable.Reset()
		fileList.tabCtx.ExecuteRules()
		log.Info("重命名页移除文件%d项", len(checkedFileList))
	})

	deleteButton.Disable()

	fileList.fileTable.Checklist.RegisterConsumer(eventbus.EventKeyWidgetChecklistChange, func(event *model.Event) {
		log.Info("重命名页选中文件变更")

		if fileList.fileTable.Checklist.GetCheckNum() > 0 {
			deleteButton.Enable()
			return
		}
		deleteButton.Disable()
	})

	submitButton := packed_widgets.NewButton("提交", theme.ConfirmIcon(), func() {
		fileList.tabCtx.Submit()
		log.Info("重命名页提交")
	})

	submitButton.Importance = widget.HighImportance

	getData := func() []interface{} {
		return lo.Map(fileList.tabCtx.FileInfos, func(item *model.ModifiedFileInfo, index int) interface{} {
			return item
		})
	}

	updateCtx := func(interfaces []interface{}) {
		fileList.tabCtx.FileInfos = lo.Map(interfaces, func(item interface{}, index int) *model.ModifiedFileInfo {
			return item.(*model.ModifiedFileInfo)
		})
		fileList.tabCtx.ExecuteRules()
		fileList.fileTable.Refresh()
	}

	fileList.toolbar = widget.NewToolbar(
		fileList.fileTable.Checklist.GetMoveUpButton(getData, updateCtx),
		fileList.fileTable.Checklist.GetMoveDownButton(getData, updateCtx),
		fileList.fileTable.Checklist.GetMoveTopButton(getData, updateCtx),
		fileList.fileTable.Checklist.GetMoveBottomButton(getData, updateCtx),
		widget.NewToolbarSpacer(),
		deleteButton,
		submitButton,
	)
}

func (fileList *RenameFileList) buildFileTable() {
	fileList.fileTable = packed_widgets.NewTable()

	fileList.fileTable.SetGetData(func(index int) interface{} {
		return fileList.tabCtx.FileInfos[index]
	})
	fileList.fileTable.SetGetDataLength(func() int {
		return len(fileList.tabCtx.FileInfos)
	})

	fileList.fileTable.AddColumn(
		packed_widgets.NewTableColumn().
			SetHeader("旧文件名").
			SetWidth(150).
			SetTextGetter(func(data interface{}) string { return data.(*model.ModifiedFileInfo).Old.Name }).
			SetOrderBy(func(asc bool) {
				fileList.tabCtx.SortFileInfos(
					util.GetComparatorByPriority[*model.ModifiedFileInfo](
						asc,
						func(a, b *model.ModifiedFileInfo) int {
							return util.CmpText(a.Old.Name, b.Old.Name)
						},
					),
				)
			}),
	)

	fileList.fileTable.AddColumn(
		packed_widgets.NewTableColumn().
			SetHeader("新文件名").
			SetWidth(150).
			SetTextGetter(func(data interface{}) string { return data.(*model.ModifiedFileInfo).New.Name }).
			SetOrderBy(func(asc bool) {
				fileList.tabCtx.SortFileInfos(
					util.GetComparatorByPriority[*model.ModifiedFileInfo](
						asc,
						func(a, b *model.ModifiedFileInfo) int {
							return util.CmpText(a.New.Name, b.New.Name)
						},
					),
				)
			}),
	)

	fileList.fileTable.AddColumn(
		packed_widgets.NewTableColumn().
			SetHeader("路径").
			SetWidth(100).
			SetTextGetter(func(data interface{}) string { return data.(*model.ModifiedFileInfo).Old.Dir }).
			SetOrderBy(func(asc bool) {
				fileList.tabCtx.SortFileInfos(
					util.GetComparatorByPriority[*model.ModifiedFileInfo](
						asc,
						func(a, b *model.ModifiedFileInfo) int {
							return util.CmpText(a.Old.Dir, b.Old.Dir)
						},
						func(a, b *model.ModifiedFileInfo) int {
							return util.CmpText(a.Old.Name, b.Old.Name)
						},
					),
				)
			}).
			SetDefaultOrder(),
	)

	fileList.fileTable.Build()

	fileList.fileTable.Checklist.RegisterConsumer(eventbus.EventKeyWidgetChecklistChange, func(event *model.Event) {
		checkIndexList := fileList.fileTable.Checklist.GetCheckIndexList()
		checkList := make([]*model.ModifiedFileInfo, len(checkIndexList))
		for i, checkIndex := range checkIndexList {
			checkList[i] = fileList.tabCtx.FileInfos[checkIndex]
		}
		fileList.tabCtx.CheckedFiles = checkList
	})

}

func newRenameFileList(tabCtx *store.RenameTabContext) *RenameFileList {
	fileList := &RenameFileList{
		tabCtx: tabCtx,
	}

	fileList.buildFileTable()
	fileList.buildToolbar()

	fileList.Container = container.NewBorder(
		fileList.toolbar,
		nil,
		nil,
		nil,
		container.NewScroll(fileList.fileTable.Table),
	)

	tabCtx.RegisterConsumer(eventbus.EventKeyRenameTabCtxResChange, func(event *model.Event) {
		log.Info("重命名页结果变更")
		fileList.fileTable.Refresh()
	})

	return fileList
}
